package com.zhiyou100.controller;

import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.text.UnicodeUtil;
import com.github.tobato.fastdfs.FastDFSClient;
import com.zhiyou100.entity.ResponseJson;
import com.zhiyou100.entity.TabDirectory;
import com.zhiyou100.entity.TabFile;
import com.zhiyou100.exception.FileException;
import com.zhiyou100.service.ITabFileService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * 文件 控制层
 *
 * @author yang
 * @version 1.0.0
 * @date 2020-10-10 17:01
 */
@Slf4j
@RestController
public class FileController {
    @Autowired
    private FastDFSClient client;
    @Autowired
    private ITabFileService service;
    //@Autowired
    //private HttpServletResponse response;


    @SneakyThrows
    @PostMapping("/file/upload.action")
    public ResponseJson<String> uploadMethod(TabDirectory directory, MultipartFile file) {
        log.debug(" directory {} , file {}", directory, file);
        if (Validator.isNull(file) || Validator.isNull(directory)) {
            throw new FileException("没有 directory 或者 file");
        }
        service.addOne(directory, file);
        return new ResponseJson<>(200, "文件上传成功！", null);
    }

    @GetMapping("/file/download/{did}.action")
    public void downloadMethod(@PathVariable("did") Integer did, HttpServletResponse response, HttpServletRequest request) throws IOException {
        log.debug(" did = {}", did);
        // 获取文件对象
        final TabFile byId = service.getById(did);
        if (Validator.isNull(byId)) {
            throw new FileException("不存在该文件 did" + did);
        }
        // 根据 文件 fid 获取一  目录对象
        final TabDirectory tabDirectory = service.selectOnByFid(did);
        // 获取文件名字
        final String fileName = tabDirectory.getDname();
        log.debug(" file name = {}", fileName);
        // 获取 HttpHeaders 设置响应头
        //final HttpHeaders httpHeaders = new HttpHeaders();
        //httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        //httpHeaders.setContentDispositionFormData("attachment", FileNameUtil.getName(fileName));
        //// 获取源文件对应的字节输出流
        //client.download(byId.getFurl(), response.getOutputStream());
        //return new ResponseEntity<>(response, httpHeaders, HttpStatus.CREATED);

        response.reset();
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/x-download");
        response.addHeader("Content-Disposition", "attachment;filename=" + encodeFileName(request, fileName));
        client.download(byId.getFurl(), response.getOutputStream());
        response.addHeader("Content-Length", byId.getFsize());
        response.setContentType("application/octet-stream;charset=UTF-8");
    }

    /**
     * 下载文件名中含有中文的处理
     *
     * @param req      域
     * @param headName 文件名
     * @return 转码后的文件名
     */
    private String encodeFileName(HttpServletRequest req, String headName)
            throws UnsupportedEncodingException {
        //IE9之前包括IE9都包含MSIE;IE10之后都包含Trident;edge浏览器包含Edge
        String msie = "MSIE";
        String trident = "Trident";
        String edge = "Edge";
        String filename = "";
        String userAgent = req.getHeader("User-Agent");
        if (userAgent.contains(msie) || userAgent.contains(trident) || userAgent.contains(edge)) {
            filename = URLEncoder.encode(headName, String.valueOf(StandardCharsets.UTF_8));

        } else {
            filename = new String(headName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        }
        return filename;
    }
}
